/**
 * @file Service_Communication.cpp
 * @author Glorill 1615688664@qq.com
 * @brief UART以及CAN通信相关
 * @version 0.1
 * @date 2022-02-04
 * 
 * @copyright Copyright (c) 2022
 * 
 */

/* Includes ------------------------------------------------------------------*/

#include "Service_Communication.h"
#include "Service_Module.h"
#include "Service_Operation.h"
#include "Service_Debug.h"

#include "Chassis.h"
#include "Pan_Tilt.h"
#include "Shoot.h"

#include "Serial_Plot.h"
#include "Vision.h"

/* Private macros ------------------------------------------------------------*/

#define Referee_RX_BUFFER_SIZE 300
#define Pan_Tilt_AHRS_RX_BUFFER_SIZE 50
#define Super_Cap_RX_BUFFER_SIZE 32
#define Vision_RX_BUFFER_SIZE 50

/* Private types -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

uint8_t Referee_Rx_Buff[Referee_RX_BUFFER_SIZE];
uint8_t Pan_Tilt_AHRS_Rx_Buff[Pan_Tilt_AHRS_RX_BUFFER_SIZE];
uint8_t Super_Cap_Rx_Buff[Super_Cap_RX_BUFFER_SIZE];
uint8_t Vision_Rx_Buff[Vision_RX_BUFFER_SIZE];
extern C_VISION Manifold;

/* Private function declarations ---------------------------------------------*/

uint32_t Referee_recv_Callback(uint8_t *Recv_Data, uint16_t ReceiveLen);
uint32_t Pan_Tilt_AHRS_recv_Callback(uint8_t *Recv_Data, uint16_t ReceiveLen);
uint32_t Super_Cap_recv_Call_back(uint8_t *buf, uint16_t len);
uint32_t Vision_recv_Callback(uint8_t *Recv_Data, uint16_t ReceiveLen);

/* Function prototypes -------------------------------------------------------*/

/**
 * @brief 裁判系统接收数据回调函数
 * 
 * @param Recv_Data 
 * @param ReceiveLen 
 * @return uint32_t 
 */
uint32_t Referee_recv_Callback(uint8_t *Recv_Data, uint16_t ReceiveLen)
{
    static BaseType_t *pxHigherPriorityTaskWoken;
    static USART_COB referee_pack;
    //	static uint8_t temp_buff[256];

    if (RecvReferee_Handle != NULL && ReceiveLen < 256)
    {
        referee_pack.address = Recv_Data;
        referee_pack.len = ReceiveLen;
        xTaskNotifyFromISR(RecvReferee_Handle, (uint32_t)&referee_pack, eSetValueWithOverwrite, pxHigherPriorityTaskWoken);
    }
    return 0;
}

/**
 * @brief 云台AHRS接收数据回调函数
 * 
 * @param Recv_Data 
 * @param ReceiveLen 
 * @return uint32_t 
 */
uint32_t Pan_Tilt_AHRS_recv_Callback(uint8_t *Recv_Data, uint16_t ReceiveLen)
{
    pan_tilt_AHRS.DataCapture(Recv_Data, ReceiveLen);
    return 0;
}

/**
 * @brief 超级电容接收数据回调函数
 * 
 * @param Recv_Data 
 * @param ReceiveLen 
 * @return uint32_t 
 */
uint32_t Super_Cap_recv_Call_back(uint8_t *Recv_Data, uint16_t ReceiveLen)
{
    SuperCap.update(Recv_Data);
    return 0;
}

/**
 * @brief 妙算接收数据回调函数
 * 
 * @param Recv_Data 
 * @param ReceiveLen 
 * @return uint32_t 
 */
uint32_t Vision_recv_Callback(uint8_t *Recv_Data, uint16_t ReceiveLen)
{
    Manifold.update(Recv_Data);
    return 0;
}

/**
 * @brief CAN1总线接收数据回调函数
 * 
 * @param CAN_RxMessage 
 */
void User_CAN1_RxCpltCallback(CAN_RxBuffer *CAN_RxMessage)
{
	switch(CAN_RxMessage->header.StdId)
	{
		case 0x201:
        {
            Wheel[0].update(CAN_RxMessage->data);
        }
        break;
		case 0x202:
        {
            Wheel[1].update(CAN_RxMessage->data);
        }
        break;
		case 0x203:
        {
            Wheel[2].update(CAN_RxMessage->data);
        }
        break;
		case 0x204:
        {
            Wheel[3].update(CAN_RxMessage->data);
        }
        break;
        case 0x205:
        {
            YawMotor.update(CAN_RxMessage->data);
        }
        break;
        case 0x210:
        {
            SuperCap.update(CAN_RxMessage->data);
        }
        break;
    }
}

/**
 * @brief CAN2总线接收数据回调函数
 * 
 * @param CAN_RxMessage 
 */
void User_CAN2_RxCpltCallback(CAN_RxBuffer *CAN_RxMessage)
{
	switch(CAN_RxMessage->header.StdId)
	{
        case 0x202:
        {
            DriveplateMotor.update(CAN_RxMessage->data);
        } 
        break;
        case 0x203:
        {
            FrictionMotor[0].update(CAN_RxMessage->data);
        }
        break;
        case 0x204:
        {
            FrictionMotor[1].update(CAN_RxMessage->data);
        }
        break;
        case 0x206:
        {
            PitchMotor.update(CAN_RxMessage->data);
        }
        break;
    }
}

/**
 * @brief 与通信相关的初始化
 * 
 */
void Service_Communication_Init(void)
{
    serial_plot.Uart_init(&huart2);
    DR16_Uart_Init();
    Uart_Init(&huart6, Referee_Rx_Buff, Referee_RX_BUFFER_SIZE, Referee_recv_Callback);
    Uart_Init(&huart7, Pan_Tilt_AHRS_Rx_Buff, Pan_Tilt_AHRS_RX_BUFFER_SIZE, Pan_Tilt_AHRS_recv_Callback);
    // Uart_Init(&huart8, Super_Cap_Rx_Buff, Super_Cap_RX_BUFFER_SIZE, SuperCap_recv_Call_back);
    Uart_Init(&huart3, Vision_Rx_Buff, Vision_RX_BUFFER_SIZE, Vision_recv_Callback);

    CAN_Init(&hcan1, User_CAN1_RxCpltCallback);
    CAN_Init(&hcan2, User_CAN2_RxCpltCallback);

    /* CAN Filter Config*/
    //麦轮c620
    CAN_Filter_Mask_Config(&hcan1, CanFilter_1 | CanFifo_0 | Can_STDID | Can_DataType, 0x201, 0x3FF);   
    //麦轮c620
    CAN_Filter_Mask_Config(&hcan1, CanFilter_2 | CanFifo_0 | Can_STDID | Can_DataType, 0x202, 0x3FF);   
    //麦轮c620
    CAN_Filter_Mask_Config(&hcan1, CanFilter_3 | CanFifo_0 | Can_STDID | Can_DataType, 0x203, 0x3FF);   
    //麦轮c620
    CAN_Filter_Mask_Config(&hcan1, CanFilter_4 | CanFifo_0 | Can_STDID | Can_DataType, 0x204, 0x3FF);   
    //云台yaw 6020
    CAN_Filter_Mask_Config(&hcan1, CanFilter_5 | CanFifo_0 | Can_STDID | Can_DataType, 0x205, 0x3FF);   
    CAN_Filter_Mask_Config(&hcan2, CanFilter_19 | CanFifo_0 | Can_STDID | Can_DataType, 0x206, 0x3ff);  //云台pitch 6020
    //拨盘 c610
    CAN_Filter_Mask_Config(&hcan2, CanFilter_20 | CanFifo_0 | Can_STDID | Can_DataType, 0x202, 0x3ff);  
    //摩擦轮 c620
    CAN_Filter_Mask_Config(&hcan2, CanFilter_21 | CanFifo_0 | Can_STDID | Can_DataType, 0x203, 0x3ff);  
    //摩擦轮 c620
    CAN_Filter_Mask_Config(&hcan2, CanFilter_22 | CanFifo_0 | Can_STDID | Can_DataType, 0x204, 0x3ff);  
    //超级电容
    CAN_Filter_Mask_Config(&hcan1, CanFilter_10 | CanFifo_0 | Can_STDID | Can_DataType, 0x210, 0x3ff); 
}

// /**
//  * @brief 数据转换
//  * 
//  * @param input Can通信内容
//  * @param output 标准数据帧
//  */
// static void Convert_Data(CAN_RxMessage* input, COB_TypeDef* output)
// {
//   output->ID = input->header.StdId;
//   output->DLC = input->header.DLC;
//   memcpy(output->Data, input->data, output->DLC);
// }

/************************ COPYRIGHT(C) USTC-ROBOWALKER **************************/
